package com.itheima.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.Dto.DishDto;
import com.itheima.VO.IdStaVO;
import com.itheima.bean.*;
import com.itheima.common.PageParm;
import com.itheima.dao.DishDao;
import com.itheima.service.CategoryService;
import com.itheima.service.DishFlavorService;
import com.itheima.service.DishService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Transactional
@Service
public class DishServiceImpl implements DishService {

    @Lazy
    @Autowired
    private CategoryService categoryService;

    @Autowired
    private DishDao dishDao;

    @Autowired
    private DishFlavorService dishFlavorService;

    @Autowired
    private RedisTemplate redisTemplate;


    /**
     * 根据分类ID查询菜品
     *
     * @param id
     * @return
     */
    @Override
    public List<Dish> findByCategoryId(long id) {

        LambdaQueryWrapper<Dish> qw = new LambdaQueryWrapper<>();
        qw.eq(Dish::getCategoryId, id);
        List<Dish> dishes = dishDao.selectList(qw);
        return dishes;

    }


    /**
     * 新增菜品同时保存对应的口味数据
     *
     * @param dishDto
     * @return
     */
    @Override
    @Transactional
    public int saveWithFlavor(DishDto dishDto) {
        //保存菜品信息到菜品表
        int row1 = dishDao.insert(dishDto);
        //往口味表添加数据
        if (row1 > 0 && dishDto.getFlavors() != null && dishDto.getFlavors().size() != 0) {
            int row2 = 0;
            for (DishFlavor flavor : dishDto.getFlavors()) {
                //设置口味属于哪一种菜
                flavor.setDishId(dishDto.getId());
                //添加口味
                row2 += dishFlavorService.insert(flavor);

            }
            return row2 == dishDto.getFlavors().size() ? 1 : 0;
        }
        return row1;
    }

    /**
     * 分页查询
     *
     * @param parm
     * @return
     */
    @Override
    public IPage<DishDto> selectPage(PageParm parm) {
        System.out.println(parm);
        IPage<Dish> dishPage = new Page<>(parm.getPage(), parm.getPageSize());
        IPage<DishDto> dishDtoPage = new Page<>();
        LambdaQueryWrapper<Dish> qw = new LambdaQueryWrapper<>();
        qw.like(parm.getName() != null, Dish::getName, parm.getName());
        qw.orderByAsc(Dish::getUpdateTime);
        dishDao.selectPage(dishPage, qw);

        //遍历每一个套餐
        List<DishDto> dishDtoList = dishPage.getRecords().stream().map((dish -> {
                    //去查询菜品的的分类数据
                    Category category = categoryService.selectById(dish.getCategoryId());
                    //构建DishDto,然后封装数据
                    DishDto dishDto = new DishDto();
                    //封装分类数据
                    dishDto.setCategoryName(category.getName());
                    //封装菜品数据
                    BeanUtils.copyProperties(dish, dishDto);
                    return dishDto;
                    //将菜品数据收集起来用Collectors.toList成List<DishDto>collect链表
                })
        ).collect(Collectors.toList());


        //设置集合数据成分页
        dishDtoPage.setRecords(dishDtoList);
        //设置总记录数
        dishDtoPage.setTotal(dishPage.getTotal());
        return dishDtoPage;
    }

    /**
     * ID查询返回菜品以及风味信息
     *
     * @param id
     * @return
     */
    @Override
    public DishDto selectByIdToDto(long id) {
        Dish dish = dishDao.selectById(id);
        List<DishFlavor> dishFlavors = dishFlavorService.selectByDishID(id);
        DishDto dishDto = new DishDto();
        BeanUtils.copyProperties(dish, dishDto);
        dishDto.setFlavors(dishFlavors);
        return dishDto;
    }

    /**
     * 更新菜品所有信息
     *
     * @param dishDto
     * @return
     */
    @Override
    public int update(DishDto dishDto) {

        //对后台菜品表做出更改，缓存应删除所有菜品信息，其他更改同样********************************

        Set dish_ = redisTemplate.keys("dish_");
        redisTemplate.delete(dish_);

        int row1 = dishDao.updateById(dishDto);
        int row2 = 0;
        if (dishDto.getFlavors() != null && dishDto.getFlavors().size() != 0) {
            dishFlavorService.delete(dishDto.getId());
            for (DishFlavor flavor : dishDto.getFlavors()) {
                flavor.setDishId(dishDto.getId());
                row2 += dishFlavorService.insert(flavor);
            }
        }
        int row = row1 + row2;
        return row;
    }

    /**
     * 修改菜品状态信息
     *
     * @param idStaVO
     * @return
     */
    @Override
    public int upStatus(IdStaVO idStaVO) {

        List<Long> ids = idStaVO.ids();
        if (ids != null && ids.size() != 0) {
            int row = 0;
            Dish dish = new Dish();
            for (Long id : ids) {
                dish.setId(id);
                dish.setStatus(idStaVO.getStatus());
                row += dishDao.updateById(dish);

            }
            return row == ids.size() ? 1 : 0;
        }
        else  return 0;
    }

    @Override
    public List<Dish> selectByCategoryID(long id) {

        LambdaQueryWrapper<Dish> qw = new LambdaQueryWrapper<>();
        qw.eq(Dish::getCategoryId, id);
        qw.eq(Dish::getStatus, 1);
        List<Dish> dishes = dishDao.selectList(qw);
        //添加排序条件
        qw.orderByAsc(Dish::getSort).orderByAsc(Dish::getUpdateTime);
        return dishes;

    }

    /**
     * 批量删除套餐所有信息
     *
     * @return
     */
    public int deleteByIds(List<Long> ids) {
        if (ids != null && ids.size() != 0) {
            for (Long id : ids) {
                Dish dish = dishDao.selectById(id);
                if(dish.getStatus()==1)
                    return 0;
            }
            int row = 0;
            for (Long id : ids) {
                dishFlavorService.delete(id);
                row+=dishDao.deleteById(id);
            }
            if (row == ids.size())
                return 1;
            else return 0;
        }
        return 0;
    }

    /**
     * 根据分类查询菜品所有信息
     * @param id
     * @return
     */
    @Override
    public List<DishDto> selectByCategoryIDUse(long id) {
        //设置redisID格式
        String key="key_"+id+"_"+1;

        List<DishDto> dishDtos = null;
        //在Redis查询KEY
        String dishDtos1 =(String) redisTemplate.opsForValue().get(key);

        dishDtos =(List<DishDto>) JSON.parse(dishDtos1);

        //如果缓存中存在，直接返回
        if(dishDtos!=null){
            return dishDtos;
        }
        //如果Redis中不存在，则查询数据，并存到Redis中
        else {
            LambdaQueryWrapper<Dish> qw = new LambdaQueryWrapper<>();
            qw.eq(Dish::getCategoryId, id);
            qw.eq(Dish::getStatus, 1);
            List<Dish> dishes = dishDao.selectList(qw);
            dishDtos = dishes.stream().map((item -> {
                List<DishFlavor> dishFlavors = dishFlavorService.selectByDishID(item.getId());
                DishDto dishDto = new DishDto();
                dishDto.setFlavors(dishFlavors);
                BeanUtils.copyProperties(item, dishDto);
                return dishDto;
            })).collect(Collectors.toList());

            String dishDto = JSON.toJSONString(dishDtos);

            //将从MYSQL查询到的数据存到Redis中
            redisTemplate.opsForValue().set(key,dishDto , 60, TimeUnit.MINUTES);

            return dishDtos;
        }

    }

}
